POJ 3580 SuperMemo (splay tree)
SuperMemo
Description Your friend, Jackson is invited to a TV show called SuperMemo in which the participant is told to play a memorizing game. At first, the host tells the participant a sequence of numbers, {A1, A2, ... An}. Then the host performs a series of operations and queries on the sequence which consists:
To make the show more interesting, the participant is granted a chance to turn to someone else that means when Jackson feels difficult in answering a query he may call you for help. You task is to watch the TV show and write a program giving the correct answer to each query in order to assist Jackson whenever he calls. Input The first line contains n (n ≤ 100000). The following n lines describe the sequence. Then follows M (M ≤ 100000), the numbers of operations and queries. The following M lines describe the operations and queries. Output For each "MIN" query, output the correct answer. Sample Input 5 1 2 3 4 5 2 ADD 2 4 1 MIN 4 5 Sample Output 5 Source POJ Founder Monthly Contest – 2008.04.13, Yao Jinyu
|
1 /* *********************************************** 2 Author :kuangbin 3 Created Time :2013/8/28 19:39:45 4 File Name :F:\2013ACM练习\专题学习\splay_tree_2\POJ3580.cpp 5 ************************************************ */ 6 7 #include <stdio.h> 8 #include <string.h> 9 #include <iostream> 10 #include <algorithm> 11 #include <vector> 12 #include <queue> 13 #include <set> 14 #include <map> 15 #include <string> 16 #include <math.h> 17 #include <stdlib.h> 18 #include <time.h> 19 using namespace std; 20 /* 21 * 给定一个数列:a1,a2,.... an 22 * 进行以下6种操作: 23 * ADD x y D : 给第x个数到第y个数加D 24 * REVERSE x y : 反转[x,y] 25 * REVOVLE x y T : 对[x,y]区间的数循环右移T次 26 * (先把T对长度取模,然后相当于把[y-T+1,y]放到[x,y-T] 的前面) 27 * INSERT x P : 在第x个数后面插入P 28 * DELETE x : 删除第x个数 29 * MIN x y : 查询[x,y]之间的最小的数 30 */ 31 #define Key_value ch[ch[root][1]][0] 32 const int MAXN = 200010; 33 const int INF = 0x3f3f3f3f; 34 int pre[MAXN],ch[MAXN][2],root,tot1,size[MAXN]; 35 int key[MAXN],rev[MAXN],m[MAXN],add[MAXN]; 36 int s[MAXN],tot2; 37 int a[MAXN]; 38 int n; 39 void NewNode(int &r,int father,int k) 40 { 41 if(tot2) r = s[tot2--]; 42 else r = ++tot1; 43 pre[r] = father; 44 ch[r][0] = ch[r][1] = 0; 45 key[r] = k; 46 m[r] = k; 47 rev[r] = add[r] = 0; 48 size[r] = 1; 49 } 50 void Update_Rev(int r) 51 { 52 if(!r)return; 53 swap(ch[r][0],ch[r][1]); 54 rev[r] ^= 1; 55 } 56 void Update_Add(int r,int D) 57 { 58 if(!r)return; 59 m[r] += D; 60 key[r] += D; 61 add[r] += D; 62 } 63 void push_up(int r) 64 { 65 size[r] = size[ch[r][0]] + size[ch[r][1]] + 1; 66 m[r] = min(key[r],min(m[ch[r][0]],m[ch[r][1]])); 67 } 68 void push_down(int r) 69 { 70 if(rev[r]) 71 { 72 Update_Rev(ch[r][0]); 73 Update_Rev(ch[r][1]); 74 rev[r] = 0; 75 } 76 if(add[r]) 77 { 78 Update_Add(ch[r][0],add[r]); 79 Update_Add(ch[r][1],add[r]); 80 add[r] = 0; 81 } 82 } 83 void Build(int &x,int l,int r,int father) 84 { 85 if(l > r)return; 86 int mid = (l+ r)/2; 87 NewNode(x,father,a[mid]); 88 Build(ch[x][0],l,mid-1,x); 89 Build(ch[x][1],mid+1,r,x); 90 push_up(x); 91 } 92 void Init() 93 { 94 root = tot1 = tot2 = 0; 95 ch[root][0] = ch[root][1] = pre[root] = 0; 96 rev[root] = add[root] = 0; 97 m[root] = INF; 98 size[root] = 0; 99 NewNode(root,0,-1); 100 NewNode(ch[root][1],root,-1); 101 for(int i = 0;i < n;i++) 102 scanf("%d",&a[i]); 103 Build(Key_value,0,n-1,ch[root][1]); 104 push_up(ch[root][1]); 105 push_up(root); 106 } 107 void Rotate(int x,int kind) 108 { 109 int y = pre[x]; 110 push_down(y); 111 push_down(x); 112 ch[y][!kind] = ch[x][kind]; 113 pre[ch[x][kind]] = y; 114 if(pre[y]) 115 ch[pre[y]][ch[pre[y]][1]==y] = x; 116 pre[x] = pre[y]; 117 ch[x][kind] = y; 118 pre[y] = x; 119 push_up(y); 120 } 121 void Splay(int r,int goal) 122 { 123 push_down(r); 124 while(pre[r] != goal) 125 { 126 if(pre[pre[r]] == goal) 127 { 128 push_down(pre[r]); 129 push_down(r); 130 Rotate(r,ch[pre[r]][0]==r); 131 } 132 else 133 { 134 push_down(pre[pre[r]]); 135 push_down(pre[r]); 136 push_down(r); 137 int y = pre[r]; 138 int kind = ch[pre[y]][0]==y; 139 if(ch[y][kind] == r) 140 { 141 Rotate(r,!kind); 142 Rotate(r,kind); 143 } 144 else 145 { 146 Rotate(y,kind); 147 Rotate(r,kind); 148 } 149 } 150 } 151 push_up(r); 152 if(goal == 0) root = r; 153 } 154 155 int Get_kth(int r,int k) 156 { 157 push_down(r); 158 int t = size[ch[r][0]] + 1; 159 if(t == k) return r; 160 if(t > k) return Get_kth(ch[r][0],k); 161 else return Get_kth(ch[r][1],k-t); 162 } 163 164 void ADD(int x,int y,int D) 165 { 166 Splay(Get_kth(root,x),0); 167 Splay(Get_kth(root,y+2),root); 168 Update_Add(Key_value,D); 169 push_up(ch[root][1]); 170 push_up(root); 171 } 172 void Reverse(int x,int y) 173 { 174 Splay(Get_kth(root,x),0); 175 Splay(Get_kth(root,y+2),root); 176 Update_Rev(Key_value); 177 push_up(ch[root][1]); 178 push_up(root); 179 } 180 void REVOLVE(int x,int y,int T) 181 { 182 int len = y - x + 1; 183 T = ( T%len + len )%len; 184 Splay(Get_kth(root,y-T+1),0); 185 Splay(Get_kth(root,y+2),root); 186 int tmp = Key_value; 187 Key_value = 0; 188 push_up(ch[root][0]); 189 push_up(root); 190 Splay(Get_kth(root,x),0); 191 Splay(Get_kth(root,x+1),root); 192 Key_value = tmp; 193 pre[tmp] = ch[root][1]; 194 push_up(ch[root][1]); 195 push_up(root); 196 } 197 void INSERT(int x,int P) 198 { 199 Splay(Get_kth(root,x+1),0); 200 Splay(Get_kth(root,x+2),root); 201 NewNode(Key_value,ch[root][1],P); 202 push_up(ch[root][1]); 203 push_up(root); 204 } 205 void erase(int r) 206 { 207 if(!r)return; 208 s[++tot2] = r; 209 erase(ch[r][0]); 210 erase(ch[r][1]); 211 } 212 void DELETE(int x) 213 { 214 Splay(Get_kth(root,x),0); 215 Splay(Get_kth(root,x+2),root); 216 erase(Key_value); 217 pre[Key_value] = 0; 218 Key_value = 0; 219 push_up(ch[root][1]); 220 push_up(root); 221 } 222 int MIN(int x,int y) 223 { 224 Splay(Get_kth(root,x),0); 225 Splay(Get_kth(root,y+2),root); 226 return m[Key_value]; 227 } 228 int main() 229 { 230 //freopen("in.txt","r",stdin); 231 //freopen("out.txt","w",stdout); 232 while(scanf("%d",&n) == 1) 233 { 234 Init(); 235 int x,y,z; 236 char op[20]; 237 int q; 238 scanf("%d",&q); 239 while(q--) 240 { 241 scanf("%s",op); 242 if(strcmp(op,"ADD") == 0) 243 { 244 scanf("%d%d%d",&x,&y,&z); 245 ADD(x,y,z); 246 } 247 else if(strcmp(op,"REVERSE") == 0) 248 { 249 scanf("%d%d",&x,&y); 250 Reverse(x,y); 251 } 252 else if(strcmp(op,"REVOLVE") == 0) 253 { 254 scanf("%d%d%d",&x,&y,&z); 255 REVOLVE(x,y,z); 256 } 257 else if(strcmp(op,"INSERT") == 0) 258 { 259 scanf("%d%d",&x,&y); 260 INSERT(x,y); 261 } 262 else if(strcmp(op,"DELETE") == 0) 263 { 264 scanf("%d",&x); 265 DELETE(x); 266 } 267 else if(strcmp(op,"MIN") == 0) 268 { 269 scanf("%d%d",&x,&y); 270 printf("%d\n",MIN(x,y)); 271 } 272 } 273 } 274 return 0; 275 }